package cn.kgc.fitler;

import cn.kgc.constant.GatewayConstant;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * <p>缓存请求体</p>
 *
 */
@Component
public class GlobalCachedRequestBodyFilter implements GlobalFilter, Ordered {

    /**
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //判断是否登陆/注册  还是一个普通的请求
        ServerHttpRequest request= exchange.getRequest();
        boolean loginOrRegister=
                request.getURI().getPath().contains(GatewayConstant.LOGIN_URL)
                        ||
                        request.getURI().getPath().contains(GatewayConstant.REGISTER_URL);
        //如果不是登录注册的请求或者请求头没有带参数,直接放行
        if(!loginOrRegister || request.getHeaders().getContentType()==null){
            return chain.filter(exchange);
        }

        return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> {
            //处理dataBuffer时，dataBuffer不能释放
            DataBufferUtils.retain(dataBuffer);

            Flux<DataBuffer> flux= Flux.defer(()->{
               return Flux.just(dataBuffer.slice(0,dataBuffer.readableByteCount()));
            });

            ServerHttpRequest serverHttpRequest=new ServerHttpRequestDecorator(request){
                @Override
                public Flux<DataBuffer> getBody() {
                    return flux;
                }
            };

            return chain.filter(exchange.mutate().request(serverHttpRequest).build());
        });
    }

    //过滤器的优先级,值越小,越靠前
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE+1;
    }
}
